package org.aldar.bquest.entity;

import org.aldar.bquest.constants.IConstants;
import org.andengine.util.math.MathUtils;

import java.util.LinkedList;
import java.util.List;

/**
 * User: Daria
 * Date: 6/5/13 8:13 PM
 */
public class ParticleTrack implements IConstants {

    private ParticleSprite mainParticle;

    int totalSteps = 300;

    int currentStep = 0;

    int stepsTrack = 100;

    float[] aXY;
    float[] bXY;
    float[] cXY;
    float[] dXY;

    float[][] lastMainXY;

    private List<ParticleSprite> track = new LinkedList<ParticleSprite>();
    private boolean alive = false;

    public ParticleTrack() {
        this.mainParticle = new ParticleSprite();
        aXY = new float[2];
        aXY[0] = IConstants.CAMERA_WIDTH;
        aXY[1] = MathUtils.random(GROUND_Y + 100, IConstants.CAMERA_HEIGHT);

        cXY = new float[2];
//        cXY[0] = MathUtils.random(0, IConstants.CAMERA_WIDTH);
//        cXY[1] = MathUtils.random(0, IConstants.CAMERA_HEIGHT);
        cXY[0] = 0;
        cXY[1] = IConstants.CAMERA_HEIGHT;

        dXY = new float[2];
//        dXY[0] = IConstants.CAMERA_WIDTH;
//        dXY[1] = IConstants.CAMERA_HEIGHT;

        //comets
        dXY[0] = 0;
        dXY[1] = GROUND_Y;

        bXY = new float[2];
        bXY[0] = cXY[0];
        bXY[1] = cXY[1];

        double length = Math.sqrt((dXY[0] - aXY[0]) * (dXY[0] - aXY[0]) + (dXY[1] - aXY[1]) * (dXY[1] - aXY[1]));
        //totalSteps = (int) length / 4;
        //stepsTrack = Math.max((int) (totalSteps * 0.1f), 1);

        lastMainXY = new float[stepsTrack][2];
        mainParticle.place(aXY[0], aXY[1]);
    }

    public void start() {
        alive = true;
    }

    public void continueMove() {
        if (alive && currentStep < totalSteps) {
            for (int i = 0; i < Math.min(currentStep, stepsTrack); i++) {
                ParticleSprite trackSprite = null;
                if (track.size() <= i) {
                    trackSprite = new ParticleSprite();
                    track.add(i, trackSprite);
                    trackSprite.setAlpha((1f / stepsTrack * (stepsTrack - i)) * (1f / stepsTrack * (stepsTrack - i)) * 0.2f);
                } else {
                    trackSprite = track.get(i);
                }
                float[] trackXY = lastMainXY[i];
                trackSprite.place(trackXY[0], trackXY[1]);
            }
            float[] xy = getCoordsForStep(currentStep, aXY, bXY);
            mainParticle.place(xy[0], xy[1]);
            adjustTarget();
        } else {
            mainParticle.remove();
            if (track.size() > 0) {
                for (int i = 0; i < track.size() - 1; i++) {
                    ParticleSprite trackSprite = track.get(i);
                    trackSprite.setAlpha(trackSprite.getSprite().getAlpha() - trackSprite.getSprite().getAlpha() / 10);
                }
                if (track.get(track.size() - 1).getSprite().getAlpha() < 0.02f || currentStep - totalSteps > 50) {
                    track.get(track.size() - 1).remove();
                    track.remove(track.size() - 1);
                }
            } else {
                alive = false;
            }

        }
        currentStep++;
    }

    private void adjustTarget() {
        for (int i = stepsTrack - 1; i > 0; i--) {
            lastMainXY[i] = lastMainXY[i - 1];
        }

        lastMainXY[0] = getCoordsForStep(currentStep, aXY, bXY);

        float[] newBXY = getCoordsForStep(currentStep, cXY, dXY);

        float[] newAXY = getStartCoordsForStep(currentStep, lastMainXY, newBXY);

        aXY = newAXY;
        bXY = newBXY;

    }

    public boolean isAlive() {
        return alive;
    }

    public int getTotalSteps() {
        return totalSteps;
    }

    public void setTotalSteps(int totalSteps) {
        this.totalSteps = totalSteps;
    }

    public int getStepsTrack() {
        return stepsTrack;
    }

    public void setStepsTrack(int stepsTrack) {
        this.stepsTrack = stepsTrack;
    }

    public float[] getCoordsForStep(int step, float xy1[], float xy2[]) {
        float newX = xy1[0] + (xy2[0] - xy1[0]) * ((float) step / totalSteps);
        float newY = xy1[1] + (xy2[1] - xy1[1]) * ((float) step / totalSteps);
        return new float[]{newX, newY};
    }

    private float[] getStartCoordsForStep(int currentStep, float[][] lastMainXY, float[] newBXY) {
        float startX = (lastMainXY[0][0] - newBXY[0] * ((float) currentStep) / totalSteps) / (1 - ((float) currentStep) / totalSteps);
        float startY = (lastMainXY[0][1] - newBXY[1] * ((float) currentStep) / totalSteps) / (1 - ((float) currentStep) / totalSteps);
        return new float[]{startX, startY};
    }

}
